#!/usr/bin/perl
package genpar;

	$VERSION = '0.1';
	require Exporter;
	BEGIN {
	    @ISA = qw(Exporter);
	    @EXPORT = qw(	getParameters 
						mergeParameters 
						readRemoteParameters 
						getNewFilesHash 
						getHashFilesUnixDos
						filterParametersByRules
						dataManipulation );
	}

use Data::Dumper; 
use genfile;
use genutil;

#------------------------------------------------------
#	Legge i 'system-parameters', 'parameters' e 'calculated-parameters' e crea %p
#------------------------------------------------------

sub getParameters {
	my ( $conf ) = @_;
	my @ar = @$conf;
	my $p;
	
	
	DEBUG( "[step]: getParameters \n" );	
	
	for( my $i=0; $i<@ar; $i++){
		$c=$ar[$i];
		if( $i==0 ){
			$p=$c;
		}else{
			$p=mergeParameters($p, $c);
		}
	}
	
	if( !exists( $p->{'cicles'} )){
		my $er='ERROR: manca $p{cicles} nella configurazione';
		OUT( $er ); die($er);
	}
	
	$p = readRemoteParameters( $p );
	return $p; 
}
#------------------------

sub mergeParameters {
	my ( $dst, $src ) = @_;
	foreach my $k (keys( %$src )){
		$dst->{$k}=$src->{$k};	
	}
	return $dst;
}
#------------------------

#-----------------------------------------------------------
#	legge i parametri remoti in JSON
#-----------------------------------------------------------
sub readRemoteParameters {
	my ( $p ) = @_;

	DEBUG( "[step]: readRemoteParameters  \n" );
	my $as;
	if( 	exists( $p->{'remote-file'})){	$as = readRemoteParametersFile( $p );	    
	}elsif(	exists( $p->{'remote-dir'})){	$as = readRemoteParametersDir( $p );	    
	}
	mergeParameters( $p, $as );
	return $p;
}

sub readRemoteParametersFile {
	my ( $p ) = @_;
	my $file = $p->{'remote-file'};
	if( !(-e $file)) {
		my $er="ATTENZIONE: 'remote-file'=$file  non esistente\n";
		OUT( $er);
		die($er);	    
	}

	DEBUG( "[step]: readRemoteParameters, JSON: $file  \n" );
	my $jsonString = leggi_file($file);

	#tolti eventuali commenti javascript
	$jsonString =~ s/^var\s*\w+\s*=//;
	$jsonString =~ s+/\*.*\*/++gs;
	$jsonString =~ s/\/\/.*\r?\n//g;

	use JSON;
	
	return decode_json( $jsonString );
}

sub readRemoteParametersDir {
	my ( $p ) = @_;
	my $dir = $p->{'remote-dir'};
	if( !(-e $dir)) {
		my $er="ATTENZIONE: 'remote-dir'=$dir  non esistente\n";
		OUT( $er);
		die($er);	    
	}

	DEBUG( "	USO LA DIR 'remote-dir' in readRemoteParameters: $dir \n" );
	return getMergedParametersFile( $dir );
}

sub getMergedParametersFile {

	my ( $dir ) = @_;
	opendir(DIR,"$dir");
	my @pkgs=readdir(DIR);
	close(DIR);
	
	my $cfg={globals => {}, cruds => {} };

	foreach my $packName (@pkgs){
		if( $packName =~ /^\./){next;}
		opendir(DIR,"$dir/$packName/");
		my @cruds=readdir(DIR);
		close(DIR);

#		my @cruds=readdir("$dir/$packName/");
		foreach my $crudName (@cruds){
			if( $crudName =~ /^\./){next;}
			my $crudStr=leggi_file("$dir/$packName/$crudName");
			$crudName=~s/\.js$//g;
			use JSON;
			my $cr = decode_json( $crudStr );
			$cfg->{cruds}->{$crudName} = $cr;
		}
	}
	return $cfg;
	#my $out = "var cfg=\n".my_json_stringify($cfg);	open(F,">$f1");	print F $out;	close(F);
}    
    
#------------------------------------------------------
#	Trasformazione dei nomi dei files e creazione hash files
#------------------------------------------------------
sub getNewFilesHash {
	my ($arrFiles, $p) = @_;
	my %p=%$p;
	
	my @files = @$arrFiles;
	my %newFile;
	foreach $f (@files) {
		$src = $dst = $f;  
		foreach $find (keys(%p)) {
			
			$src = interpolazioneStringaConHash( $f,  $p{'src'} ); 
			$dst = interpolazioneStringaConHash( $f,  $p{'dst'} ); 
		}
		$newFile{$src} = $dst;
	}
	#print Dumper(\%newFile); die (1);
	return \%newFile;
}
#------------------------

sub getHashFilesUnixDos {
	my ($arrFiles, $p) = @_;
	my %p=%$p;

	my @files = @$arrFiles;
	my %targetFile;
	
	foreach $f (@files) {
		my $unixName=interpolazioneStringaConHash( $f,  $p{'dst'} ); 
		my $dosName=$unixName;
		$dosName =~ s+^/c/+c:\\+i; 
		$dosName =~ s+/+\\+g; 
		$targetFile{$unixName} = $dosName;
	}
	#print Dumper(\%targetFile); die (1);
	return \%targetFile;
}
#------------------------

#######################################
#	FILTRI SU ATTRIBUTI
#######################################
sub excludeAttributeByRules{
    #permette di filtrare le colonne attributo dell'entita $formfields in base a $ruleName.
    #questo è una stringa contenente una espressione booleana che indica se una colonna va esclusa o meno
    #se la stringa è vuota, allora non ci sono regole di esclusione. quindi si ritorna l'array senza modificarlo
    #ritorna l'array degli attributi che non corrispondono alla regola
    my ($formfields, $p, $ruleName) = @_;
    
    if($ruleName eq ''){
	    return $formfields;
    }
    my %p=%$p;
    my @cols;
    foreach my $a (@$formfields){
	    my %a=%$a;
	    my $exclude='';
	    my $cmd="if( $ruleName ){\$exclude='true'}";
	    eval $cmd;
	    if($@){
		die("Error in rules. Rule::\n$ruleName:\nError:\n$@");
	    }
	    if($exclude eq ''){
		    push @cols, $a;
	    }
    }
    return \@cols;
}
#------------------------------------------------------------------------------------------------


sub includeAttributeByRules{
    #permette di filtrare le colonne attributo dell'entita $formfields in base a $ruleName.
    #ritorna l'array degli attributi che corrispondono alla regola
    my ($formfields, $p, $ruleName) = @_;
    
    if($ruleName eq ''){
	    return $formfields;
    }
    my %p=%$p;
    my @cols;
    foreach my $a (@$formfields){
	    my %a=%$a;
	    my $exclude='true';
	    my $cmd="if( $ruleName ){\$exclude=''}";
	    eval $cmd;
	    if($@){
		die("Error in rules. Rule::\n$ruleName:\nError:\n$@");
	    }
	    if($exclude eq ''){
		    push @cols, $a;
	    }
    }
    return \@cols;
}
#------------------------------------------------------------------------------------------------

sub filterParametersByRules{
    #compatibiltà: chiama excludeAttributeByRules
    my ($formfields, $p, $ruleName) = @_;

    ## TODO: deve diventare
    ## return excludeAttributeByRules($formfields, $p, $ruleName);
    
    if($ruleName eq ''){
	    return $formfields;
    }
    my %p=%$p;
    my @cols;
    foreach my $a (@$formfields){
	    my %a=%$a;
	    my $exclude='';
	    my $cmd="if( $ruleName ){\$exclude='true'}";
	    eval $cmd;
	    if($@){
		die("Error in rules. Rule::\n$ruleName:\nError:\n$@");
	    }
	    if($exclude eq ''){
		    push @cols, $a;
	    }
    }
    return \@cols;
}
#------------------------------------------------------------------------------------------------

#######################################
#	Manipulazione attributi $a
#######################################
sub dataManipulation{
    #permette di manipolare gli attributio con i comandi contenuti in
    # $p->{dataManipulation} 
    # tali comandi si riferiscono a $a

    my ($formfields, $p ) = @_;
    my %p=%$p;
    my @cols;
	
	if( ! exists $p->{dataManipulation} ) {
		return;
	}
	
	my $rules=$p->{dataManipulation};
    
    foreach my $rule (values( %$rules )){		
		foreach my $a (@$formfields){
			my %a=%$a;
			eval $rule;
			if($@){
				die("Error in rules. Rule::\n$rule:\nError:\n$@");
			}
		}
	}
}
#------------------------------------------------------------------------------------------------

1;
